<?php

namespace WebmanGrpc\Module;

use WebmanGrpc\Module\ModuleInterface;

/**
 * 基础模块类
 * 
 * 提供模块的基础实现
 */
abstract class BaseModule implements ModuleInterface
{
    /**
     * 模块名称
     * @var string
     */
    protected string $name;
    
    /**
     * 模块版本
     * @var string
     */
    protected string $version;
    
    /**
     * 模块依赖
     * @var array
     */
    protected array $dependencies;
    
    /**
     * 模块配置
     * @var array
     */
    protected array $config;
    
    /**
     * 模块状态
     * @var array
     */
    protected array $status;
    
    /**
     * 是否已初始化
     * @var bool
     */
    protected bool $initialized = false;
    
    /**
     * 是否已启动
     * @var bool
     */
    protected bool $started = false;
    
    /**
     * 构造函数
     * 
     * @param string $name 模块名称
     * @param string $version 模块版本
     * @param array $dependencies 模块依赖
     */
    public function __construct(string $name, string $version, array $dependencies = [])
    {
        $this->name = $name;
        $this->version = $version;
        $this->dependencies = $dependencies;
        $this->config = [];
        $this->status = [
            'initialized' => false,
            'started' => false,
            'start_time' => null,
            'uptime' => 0,
        ];
    }
    
    /**
     * {@inheritdoc}
     */
    public function getName(): string
    {
        return $this->name;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getVersion(): string
    {
        return $this->version;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getDependencies(): array
    {
        return $this->dependencies;
    }
    
    /**
     * {@inheritdoc}
     */
    public function initialize(array $config = []): void
    {
        if ($this->initialized) {
            return;
        }
        
        $this->config = array_merge($this->getDefaultConfig(), $config);
        $this->doInitialize();
        $this->initialized = true;
        $this->status['initialized'] = true;
    }
    
    /**
     * {@inheritdoc}
     */
    public function start(): void
    {
        if (!$this->initialized) {
            throw new \RuntimeException("Module '{$this->name}' must be initialized before starting");
        }
        
        if ($this->started) {
            return;
        }
        
        $this->doStart();
        $this->started = true;
        $this->status['started'] = true;
        $this->status['start_time'] = time();
    }
    
    /**
     * {@inheritdoc}
     */
    public function stop(): void
    {
        if (!$this->started) {
            return;
        }
        
        $this->doStop();
        $this->started = false;
        $this->status['started'] = false;
        $this->status['uptime'] = time() - $this->status['start_time'];
        $this->status['start_time'] = null;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getStatus(): array
    {
        // 更新运行时间
        if ($this->started && $this->status['start_time']) {
            $this->status['uptime'] = time() - $this->status['start_time'];
        }
        
        return array_merge($this->status, $this->getAdditionalStatus());
    }
    
    /**
     * 获取默认配置
     * 
     * @return array 默认配置
     */
    protected function getDefaultConfig(): array
    {
        return [];
    }
    
    /**
     * 执行初始化逻辑
     * 
     * @return void
     */
    protected function doInitialize(): void
    {
        // 子类实现具体的初始化逻辑
    }
    
    /**
     * 执行启动逻辑
     * 
     * @return void
     */
    protected function doStart(): void
    {
        // 子类实现具体的启动逻辑
    }
    
    /**
     * 执行停止逻辑
     * 
     * @return void
     */
    protected function doStop(): void
    {
        // 子类实现具体的停止逻辑
    }
    
    /**
     * 获取额外状态信息
     * 
     * @return array 额外状态信息
     */
    protected function getAdditionalStatus(): array
    {
        return [];
    }
    
    /**
     * 获取配置值
     * 
     * @param string $key 配置键
     * @param mixed $default 默认值
     * @return mixed 配置值
     */
    protected function getConfig(string $key, $default = null)
    {
        return $this->config[$key] ?? $default;
    }
    
    /**
     * 设置配置值
     * 
     * @param string $key 配置键
     * @param mixed $value 配置值
     * @return void
     */
    protected function setConfig(string $key, $value): void
    {
        $this->config[$key] = $value;
    }
    
    /**
     * 设置状态值
     * 
     * @param string $key 状态键
     * @param mixed $value 状态值
     * @return void
     */
    protected function setStatus(string $key, $value): void
    {
        $this->status[$key] = $value;
    }
    
    /**
     * 检查是否已初始化
     * 
     * @return bool 是否已初始化
     */
    public function isInitialized(): bool
    {
        return $this->initialized;
    }
    
    /**
     * 检查是否已启动
     * 
     * @return bool 是否已启动
     */
    public function isStarted(): bool
    {
        return $this->started;
    }
}